/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2021年5月23日
 */
package com.massyframework.beanskin;

import java.io.Serializable;

import com.massyframework.beanskin.service.ServiceReference;
import com.massyframework.beanskin.util.version.Version;

/**
 * 简单的模块身份标识符
 * @author huangkh
 *
 */
public final class SimpleModuleIdentifier implements ModuleIdentifier, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5233065723081940486L;
	private String groupId;
	private String moduleId;
	private Version version;

	/**
	 * 
	 */
	protected SimpleModuleIdentifier() {
	}
	
	/**
	 * 使用{@code builder}创建模块标识符实例
	 * @param builder {@link Builder}
	 */
	private SimpleModuleIdentifier(Builder builder) {
		this.groupId = builder.groupId;
		this.moduleId = builder.moduleId;
		this.version = builder.version;
	}

	@Override
	public String getGroupId() {
		return this.groupId;
	}

	@Override
	public String getModuleId() {
		return this.moduleId;
	}

	@Override
	public Version getVersion() {
		return this.version;
	}
	

	@Override
	public int compareTo(ModuleIdentifier o) {
		int result = this.getGroupId().compareTo(o.getGroupId());
		if (result == 0) {
			result = this.getModuleId().compareTo(o.getModuleId());
			if (result == 0) {
				return this.getVersion().compareTo(o.getVersion());
			}
		}
		return result;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((groupId == null) ? 0 : groupId.hashCode());
		result = prime * result + ((moduleId == null) ? 0 : moduleId.hashCode());
		result = prime * result + ((version == null) ? 0 : version.hashCode());
		
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!ModuleIdentifier.class.isAssignableFrom(obj.getClass()))
			return false;
		
		ModuleIdentifier other = (ModuleIdentifier) obj;
		if (!groupId.equals(other.getGroupId())) {
			return false;
		}
		
		if (!moduleId.equals(other.getModuleId())) {
			return false;
		}
		
		if (!version.equals(other.getVersion())) {
			return false;
		}
		return true;
	}
	
	

	@Override
	public String toString() {
		return "ModuleIdentifier [groupId=" + groupId + ", moduleId=" + moduleId + ", version=" + version + "]";
	}

	/**
	 * 创建构建器实例
	 * @return {@link Builder}
	 */
	public static Builder newBuilder() {
		return new Builder();
	}
	
	/**
	 * 克隆{@code module}的标识符
	 * @param module {@link Module}
	 * @return {@link Builder}
	 */
	public static Builder clone(Module<?> module) {
		return new Builder()
				.groupId(module.getGroupId())
				.moduleId(module.getModuleId())
				.version(module.getVersion());
	}
	
	/**
	 * 创建系统内核模块标识符
	 * @return {@link ModuleIdentifier}
	 */
	public static ModuleIdentifier createModuleIdentifierWithKernel() {
		return newBuilder()
				.groupId("com.massyframework.beanskin")
				.moduleId("beanskin-runtime-core")
				.version(Version.parseVersion("2.0.0"))
				.build();
	}
	
	/**
	 * 创建和{@code reference}注册模块等同的标识符
	 * @param reference {@link ServiceReference},服务引用
	 * @return {@link ModuleIdentifier}
	 */
	public static ModuleIdentifier createModuleIdentifier(ServiceReference<?> reference) {
		return newBuilder()
				.groupId(reference.getGroupId())
				.moduleId(reference.getModuleId())
				.version(reference.getModuleVersion())
				.build();
	}
	
	/**
	 * 创建和{@code identifierString}相匹配的模块标识符
	 * @param identifierString {@link String}
	 * @return {@link ModuleIdentifier}
	 */
	public static ModuleIdentifier createModuleIdentifier(String identifierString) {
		String[] arr = identifierString.split(COLON);
		if (arr.length != 3) {
			throw new IllegalArgumentException("\"identifierString\" is not valid format.");
		}
		
		return newBuilder()
				.groupId(arr[0])
				.moduleId(arr[1])
				.version(Version.parseVersion(arr[2]))
				.build();
	}
	
	public static class Builder {
		private String groupId;
		private String moduleId;
		private Version version;

		/**
		 * 设置组编号
		 * @param groupId {@link String} 
		 * @return {@link Builder}
		 */
		public Builder groupId(String groupId) {
			this.groupId = groupId;
			return this;
		}

		/**
		 * 设置模块编号
		 * @param moduleId {@link String}
		 * @return {@link Builder}
		 */
		public Builder moduleId(String moduleId) {
			this.moduleId = moduleId;
			return this;
		}

		/**
		 * 设置版本
		 * @param version {@link Version}
		 * @return {@link Builder}
		 */
		public Builder version(Version version) {
			this.version = version;
			return this;
		}

		/**
		 * 创建简单模块标识符
		 * @return {@link SimpleModuleIdentifier}
		 */
		public SimpleModuleIdentifier build() {
			return new SimpleModuleIdentifier(this);
		}
	}

	
}
